/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package runebound.ui.mapa;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import runebound.manejadores.RBControladorJuego;
import runebound.manejadores.eventos.RBEventoDadoMovimientoSeleccionado;
import runebound.random.RBAzar;
import runebound.ui.RBPalentaColores;

/**
 *
 * @author Miguel (alakat@gmail.com)
 */
public class RBDadosMovimientoPanel  extends JPanel implements MouseListener{
    
    
    public static final int X_SEPARACION=10;
    public static final int Y_SEPARACION=10;
    public static final int DADOS_SEPARACION=10;
    
    
    private DadosMovimientoPanelEstados estado;
    private List<Terreno[]> tirada;
    private List<DadoMovimientoEstado> estadoDeDados;
    private Terreno[] dadoSelecionado;
    

    @Override
    public void mouseClicked(MouseEvent e) {
        
        switch(this.estado){
            case ESPERA:
                this.setLanzarDados(5); //TODO tener encuenta fatiga
                break;
            case DADOS_LANZADOS:
                
                break;
            case DADOS_RESUELTOS:
                //this.setNuevoTurno();
                Rectangle[] rect  = this.getClipsDados();
                for (int i = 0; i < rect.length; i++) {
                    Rectangle rect1 = rect[i];
                    if(this.estadoDeDados.get(i)!=DadoMovimientoEstado.USADO
                            && rect1.contains(e.getPoint())){
                        this.setDadoVisualizado(i);
                    }
                }
                break;
        }
        repaint();
     
    }

    @Override
    public void mousePressed(MouseEvent e) {
     
    }

    @Override
    public void mouseReleased(MouseEvent e) {
     
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        
    }

    @Override
    public void mouseExited(MouseEvent e) {
        
    }

    private void privatePaintEspera(Graphics g) {
        Dimension d = this.getSize();
        g.drawString("Clic aquí para lazar dados", 15, d.height/2);
    }

    private void privatePaintLanzados(Graphics g) {
        //TODO animacion
    }

    /**
     * Pinta los dados 
     * @param g 
     */
    private void privatePaintResueltos(Graphics g) {
        int index = 0;
        Rectangle[] clipsDados = this.getClipsDados();
        for (Terreno[] dado : tirada) {
            this.paintDado(dado,
                    g.create(clipsDados[index].x,
                            clipsDados[index].y,
                            clipsDados[index].width,
                            clipsDados[index].height),clipsDados[index],index);
            
            index++;
        }
    }

    /**
     * Pinta un dado con el 
     * @param dado
     * @param graphics 
     */
    private void paintDado(Terreno[] dado, Graphics g,Rectangle r,int index) {
        
        if(this.estadoDeDados.get(index)==DadoMovimientoEstado.ESPERA){
            
        }else if(this.estadoDeDados.get(index)==DadoMovimientoEstado.VISUALIZACION){
            g.setColor(RBPalentaColores.getInstance().getDadoVisualizadoColor());
            g.fillRoundRect(1, 1, r.width-1, r.height-1, r.width/10, r.height/10);
        }else if(this.estadoDeDados.get(index)==DadoMovimientoEstado.USADO){
            g.setColor(RBPalentaColores.getInstance().getDadoUsadoColor());
            g.fillRoundRect(1, 1, r.width-1, r.height-1, r.width/10, r.height/10);
        }
        if(dado.length==2){
            g.setColor(Color.black);
            Shape circle = new Ellipse2D.Float(0f,0f,20.0f,20.0f);
            paintDadoTerreno(g.create(5, 15, 20, 20), circle,dado[0]);
            circle       = new Ellipse2D.Float(0f,0f,20.0f,20.0f);
            paintDadoTerreno(g.create(30, 15, 20, 20), circle,dado[1]);
        }else if(dado.length==3){
            g.setColor(Color.black);
            Shape circle = new Ellipse2D.Float(0.0f,0.0f,15.0f,15.0f);
            paintDadoTerreno(g.create(5, 15, 15, 15), circle,dado[0]);
            circle       = new Ellipse2D.Float(0.0f,0.0f,15.0f,15.0f);
            paintDadoTerreno(g.create(30, 15, 15, 15), circle,dado[1]);
            circle       = new Ellipse2D.Float(0.0f,0.0f,15.0f,15.0f);
            paintDadoTerreno(g.create(20, 35, 15, 15), circle,dado[2]);
        }else{
            System.err.println("ERROR tirada de dados anómala");
        }
        g.setColor(Color.BLACK);
        g.drawRoundRect(1, 1, r.width-1, r.height-1, r.width/10, r.height/10);
        
    }

    private void paintDadoTerreno(Graphics g, Shape circle,Terreno t) {
        if(t!= Terreno.RIO && t!= Terreno.CAMINO){
            g.setColor(RBPalentaColores.getInstance().getColorByTerreno(t));
            ((Graphics2D)g).fill(circle);
        }else{
            g.setColor(Color.black);
            ((Graphics2D)g).draw(circle);
            Rectangle r = circle.getBounds();
            g.setColor(RBPalentaColores.getInstance().getColorByTerreno(t));
            g.drawLine(0  , 0, r.width, r.height);
        }
        
    }

    /**
     * Detemina el dado que el sistema esta mostrando su alcance.
     * Informa al control del juego del cambio de alcance
     * @param i 
     */
    private void setDadoVisualizado(int i) {
        for (int j = 0; j < this.estadoDeDados.size(); j++) {
            DadoMovimientoEstado estado = this.estadoDeDados.get(j);
            if(estado!=DadoMovimientoEstado.USADO){
                this.estadoDeDados.remove(j);
                this.estadoDeDados.add(j, DadoMovimientoEstado.ESPERA);
            }
        }
        this.estadoDeDados.remove(i);
        this.estadoDeDados.add(i, DadoMovimientoEstado.VISUALIZACION);
        this.dadoSelecionado = this.tirada.get(i);
        RBControladorJuego.getInstance().recibirEvento(
            new RBEventoDadoMovimientoSeleccionado(this.dadoSelecionado));
        
    }
    /**
     * Define los posibles estados que habrá en el panel donde se 
     * muestran los movimientos
     */
    private enum DadosMovimientoPanelEstados{
        ESPERA, DADOS_LANZADOS, DADOS_RESUELTOS
    }
    
    /**
     * Define los posibles estados que puede tener un dado  con respecto a la 
     * lógica del movimiento
     */
    private enum DadoMovimientoEstado{
        ESPERA, VISUALIZACION, USADO
    };

    
    
    public RBDadosMovimientoPanel() {
        this.estado=DadosMovimientoPanelEstados.ESPERA;
        this.estadoDeDados = new ArrayList<DadoMovimientoEstado>();
        
        this.addMouseListener(this);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g); 
        switch(this.estado){
            case ESPERA:
                this.privatePaintEspera(g);
                break;
            case DADOS_LANZADOS:
                this.privatePaintLanzados(g);
                break;
            case DADOS_RESUELTOS:
                this.privatePaintResueltos(g);
                break;
        }
    }
    
    
    public void setNuevoTurno(){
        this.estado=DadosMovimientoPanelEstados.ESPERA;
        this.dadoSelecionado=null;
        this.estadoDeDados.clear();
        this.repaint();
        
    }
    
    public void setLanzarDados(int nDados){
        //TODO hebra de animación de dados;
        this.setTiradaCompletada(nDados);
        this.repaint();
    }
    
    private void setTiradaCompletada(int nDados){
        this.tirada = RBAzar.getInstance().getTiraraMovimiento(nDados);
        this.estado = DadosMovimientoPanelEstados.DADOS_RESUELTOS;
        for (int i = 0; i < nDados; i++) {
            this.estadoDeDados.add(DadoMovimientoEstado.ESPERA);
        }
        this.repaint();
    }
    
    /**
     * Nos indica si hay algún dado seleccionado
     * @return 
     */
    public boolean isDadoSeleccionado(){
        
        return this.dadoSelecionado!=null;
    }
    
    
    /**
     * Genera los rectangulos donde se pintarán los dados
     * @return 
     */
    public Rectangle[] getClipsDados(){
        //int nDados = this.tirada.size();
        int nDados = 5; //Mejor no ampliar
        int withReal = (this.getWidth()-(2*RBDadosMovimientoPanel.X_SEPARACION)
                              -(nDados*RBDadosMovimientoPanel.DADOS_SEPARACION))/nDados;
        int heightReal = this.getHeight()-(2*RBDadosMovimientoPanel.Y_SEPARACION);
        int xacumulada = RBDadosMovimientoPanel.X_SEPARACION;
        Rectangle[] rectangulos =  new Rectangle[this.tirada.size()];
        for (int i = 0; i < rectangulos.length; i++) {
            Point p = new Point(xacumulada,heightReal/4);
            xacumulada+=withReal+DADOS_SEPARACION;
            rectangulos[i]=new Rectangle(p, new Dimension(withReal, heightReal/2));
        };
        return rectangulos;
    }
    
    /**
     * Se marca el dado como ya utilizado
     */
    public void setDadoUsado(){
        for (int j = 0; j < this.estadoDeDados.size(); j++) {
            DadoMovimientoEstado estado = this.estadoDeDados.get(j);
            if(estado==DadoMovimientoEstado.VISUALIZACION){
                this.estadoDeDados.remove(j);
                this.estadoDeDados.add(j, DadoMovimientoEstado.USADO);
            }
        }
    }
    
    
}
